#include "StdAfx.h"
#include "DriverD3D.h"
#include "D3DMemReplayDevice.h"

#ifdef MEMREPLAY_WRAP_D3D9

CMemReplayDirect3DDevice9::CMemReplayDirect3DDevice9(IDirect3DDevice9* pWrap)
	: m_pWrap(pWrap)
{
}

HRESULT CMemReplayDirect3DDevice9::QueryInterface(REFIID riid, void** ppvObj)
{
  return m_pWrap->QueryInterface(riid, ppvObj);
}
ULONG CMemReplayDirect3DDevice9::AddRef()
{
  return m_pWrap->AddRef();
}
ULONG CMemReplayDirect3DDevice9::Release()
{
  return m_pWrap->Release();
}

  /*** IDirect3DDevice9 methods ***/
HRESULT CMemReplayDirect3DDevice9::TestCooperativeLevel()
{
  return m_pWrap->TestCooperativeLevel();
}

UINT CMemReplayDirect3DDevice9::GetAvailableTextureMem()
{
  return m_pWrap->GetAvailableTextureMem();
}

HRESULT CMemReplayDirect3DDevice9::EvictManagedResources()
{
  return m_pWrap->EvictManagedResources();
}

HRESULT CMemReplayDirect3DDevice9::GetDirect3D(IDirect3D9** ppD3D9)
{
  return m_pWrap->GetDirect3D(ppD3D9);
}

HRESULT CMemReplayDirect3DDevice9::GetDeviceCaps(D3DCAPS9* pCaps)
{
  return m_pWrap->GetDeviceCaps(pCaps);
}

HRESULT CMemReplayDirect3DDevice9::GetDisplayMode(UINT iSwapChain,D3DDISPLAYMODE* pMode)
{
  return m_pWrap->GetDisplayMode(iSwapChain, pMode);
}

HRESULT CMemReplayDirect3DDevice9::GetCreationParameters(D3DDEVICE_CREATION_PARAMETERS *pParameters)
{
  return m_pWrap->GetCreationParameters(pParameters);
}

HRESULT CMemReplayDirect3DDevice9::SetCursorProperties(UINT XHotSpot,UINT YHotSpot,IDirect3DSurface9* pCursorBitmap)
{
  return m_pWrap->SetCursorProperties(XHotSpot,YHotSpot,pCursorBitmap);
}

void CMemReplayDirect3DDevice9::SetCursorPosition(int X,int Y,DWORD Flags)
{
  return m_pWrap->SetCursorPosition(X,Y,Flags);
}

BOOL CMemReplayDirect3DDevice9::ShowCursor(BOOL bShow)
{
  return m_pWrap->ShowCursor(bShow);
}


HRESULT CMemReplayDirect3DDevice9::CreateAdditionalSwapChain(D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain9** pSwapChain)
{
  return m_pWrap->CreateAdditionalSwapChain( pPresentationParameters, pSwapChain);
}

HRESULT CMemReplayDirect3DDevice9::GetSwapChain(UINT iSwapChain,IDirect3DSwapChain9** pSwapChain)
{
  return m_pWrap->GetSwapChain(iSwapChain,pSwapChain);
}

UINT CMemReplayDirect3DDevice9::GetNumberOfSwapChains()
{
  return m_pWrap->GetNumberOfSwapChains();
}    

HRESULT CMemReplayDirect3DDevice9::Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion)
{
  return m_pWrap->Present(pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion);
}

HRESULT CMemReplayDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters)
{
  return m_pWrap->Reset(pPresentationParameters);
}

HRESULT CMemReplayDirect3DDevice9::GetBackBuffer(UINT iSwapChain,UINT iBackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface9** ppBackBuffer)
{
  return m_pWrap->GetBackBuffer(iSwapChain,iBackBuffer,Type,ppBackBuffer);
}

HRESULT CMemReplayDirect3DDevice9::GetRasterStatus(UINT iSwapChain,D3DRASTER_STATUS* pRasterStatus)
{
  return m_pWrap->GetRasterStatus(iSwapChain,pRasterStatus);
}

HRESULT CMemReplayDirect3DDevice9::SetDialogBoxMode(BOOL bEnableDialogs)
{
  return m_pWrap->SetDialogBoxMode(bEnableDialogs);
}

void CMemReplayDirect3DDevice9::SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp)
{
  return m_pWrap->SetGammaRamp(iSwapChain,Flags,pRamp);
}

void CMemReplayDirect3DDevice9::GetGammaRamp(UINT iSwapChain,D3DGAMMARAMP* pRamp)
{
  return m_pWrap->GetGammaRamp(iSwapChain,pRamp);
}

static size_t ComputeSizeOfSurface(D3DFORMAT fmt, UINT width, UINT height)
{
	switch (fmt)
	{
	default:
	case D3DFMT_UNKNOWN:
		return 0;

	case D3DFMT_R3G3B2:
	case D3DFMT_A8:
	case D3DFMT_P8:
	case D3DFMT_L8:
		return width * height;

	case D3DFMT_R5G6B5:
	case D3DFMT_X1R5G5B5:
	case D3DFMT_A1R5G5B5:
	case D3DFMT_A4R4G4B4:
	case D3DFMT_A8R3G3B2:
	case D3DFMT_X4R4G4B4:
	case D3DFMT_A8P8:
	case D3DFMT_A8L8:
	case D3DFMT_A4L4:
	case D3DFMT_V8U8:
	case D3DFMT_L6V5U5:
	case D3DFMT_D16_LOCKABLE:
	case D3DFMT_D15S1:
	case D3DFMT_D16:
	case D3DFMT_INDEX16:
	case D3DFMT_L16:
	case D3DFMT_R16F:
		return width * height * 2;

	case D3DFMT_R8G8B8:
		return width * height * 3;

	case D3DFMT_A8R8G8B8:
	case D3DFMT_X8R8G8B8:
	case D3DFMT_A2B10G10R10:
	case D3DFMT_A8B8G8R8:
	case D3DFMT_X8B8G8R8:
	case D3DFMT_G16R16:
	case D3DFMT_A2R10G10B10:
	case D3DFMT_X8L8V8U8:
	case D3DFMT_Q8W8V8U8:
	case D3DFMT_V16U16:
	case D3DFMT_A2W10V10U10:
	case D3DFMT_D32:
	case D3DFMT_D24S8:
	case D3DFMT_D24X8:
	case D3DFMT_D24X4S4:
	case D3DFMT_D32F_LOCKABLE:
	case D3DFMT_D24FS8:
	case D3DFMT_INDEX32:
	case D3DFMT_R32F:
	case D3DFMT_G16R16F:
	case D3DFMT_MULTI2_ARGB8:
		return width * height * 4;

	case D3DFMT_A16B16G16R16:
	case D3DFMT_G32R32F:
	case D3DFMT_A16B16G16R16F:
	case D3DFMT_Q16W16V16U16:
		return width * height * 8;

	case D3DFMT_A32B32G32R32F:
		return width * height * 16;


		//case D3DFMT_UYVY:
		//case D3DFMT_R8G8_B8G8:
		//case D3DFMT_YUY2:
		//case D3DFMT_G8R8_G8B8:

	case D3DFMT_DXT1:
		return width * height / 2;

	case D3DFMT_DXT2:
	case D3DFMT_DXT3:
	case D3DFMT_DXT4:
	case D3DFMT_DXT5:
		return width * height;

	//case D3DFMT_VERTEXDATA:
		//case D3DFMT_CxV8U8:
	}
}

HRESULT CMemReplayDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateTexture(Width,Height,Levels,Usage,Format,Pool,ppTexture,pSharedHandle);
	if (!FAILED(hr))
	{
		size_t size = 0;

		IDirect3DTexture9* pTexture = *ppTexture;
		for (DWORD l = 0, lc = pTexture->GetLevelCount(); l != lc; ++ l)
		{
			D3DSURFACE_DESC desc;
			memset(&desc, 0, sizeof(desc));
			pTexture->GetLevelDesc(l, &desc);
			size += ComputeSizeOfSurface(desc.Format, desc.Width, desc.Height);
		}

		MemReplayAnnotateD3DResource(*ppTexture, Pool, size);
	}
	return hr;
}

HRESULT CMemReplayDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateVolumeTexture(Width,Height,Depth,Levels,Usage,Format,Pool,ppVolumeTexture,pSharedHandle);
	if (!FAILED(hr))
	{
		size_t size = 0;
		IDirect3DVolumeTexture9* pTexture = *ppVolumeTexture;
		for (DWORD l = 0, lc = pTexture->GetLevelCount(); l != lc; ++ l)
		{
			D3DVOLUME_DESC desc;
			memset(&desc, 0, sizeof(desc));
			pTexture->GetLevelDesc(l, &desc);
			size += desc.Width * desc.Height * desc.Depth;
		}

		MemReplayAnnotateD3DResource(*ppVolumeTexture, Pool, size);
	}
	return hr;
}

HRESULT CMemReplayDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateCubeTexture(EdgeLength,Levels,Usage,Format,Pool,ppCubeTexture,pSharedHandle);
	if (!FAILED(hr))
	{
		size_t size = 0;
		IDirect3DCubeTexture9* pTexture = *ppCubeTexture;
		for (DWORD l = 0, lc = pTexture->GetLevelCount(); l != lc; ++ l)
		{
			D3DSURFACE_DESC desc;
			memset(&desc, 0, sizeof(desc));
			pTexture->GetLevelDesc(l, &desc);
			size += ComputeSizeOfSurface(desc.Format, desc.Width, desc.Height);
		}
		MemReplayAnnotateD3DResource(*ppCubeTexture, Pool, size * 6);
	}
	return hr;
}

HRESULT CMemReplayDirect3DDevice9::CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateVertexBuffer(Length,Usage,FVF,Pool, ppVertexBuffer, pSharedHandle);
	if (!FAILED(hr))
		MemReplayAnnotateD3DResource(*ppVertexBuffer, Pool, Length);

	return hr;
}

HRESULT CMemReplayDirect3DDevice9::CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateIndexBuffer(Length,Usage,Format,Pool, ppIndexBuffer,pSharedHandle);
	if (!FAILED(hr))
		MemReplayAnnotateD3DResource(*ppIndexBuffer, Pool, Length);

	return hr;
}


HRESULT CMemReplayDirect3DDevice9::CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateRenderTarget(Width,Height,Format,MultiSample,MultisampleQuality,Lockable, ppSurface, pSharedHandle );
	if (!FAILED(hr))
		MemReplayAnnotateD3DResource(*ppSurface, D3DPOOL_DEFAULT, Width * Height);

	return hr;
}


HRESULT CMemReplayDirect3DDevice9::CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle)
{
	HRESULT hr = m_pWrap->CreateDepthStencilSurface(Width,Height,Format,MultiSample,MultisampleQuality,Discard, ppSurface, pSharedHandle );
	if (!FAILED(hr))
		MemReplayAnnotateD3DResource(*ppSurface, D3DPOOL_DEFAULT, Width * Height);

	return hr;
}


HRESULT CMemReplayDirect3DDevice9::UpdateSurface(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestinationSurface,CONST POINT* pDestPoint)
{
  return m_pWrap->UpdateSurface(pSourceSurface,pSourceRect,pDestinationSurface, pDestPoint);
}

HRESULT CMemReplayDirect3DDevice9::UpdateTexture(IDirect3DBaseTexture9* pSourceTexture,IDirect3DBaseTexture9* pDestinationTexture)
{
  return m_pWrap->UpdateTexture(pSourceTexture,pDestinationTexture);
}

HRESULT CMemReplayDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface)
{
  return m_pWrap->GetRenderTargetData(pRenderTarget,pDestSurface);
}

HRESULT CMemReplayDirect3DDevice9::GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface)
{
  return m_pWrap->GetFrontBufferData(iSwapChain,pDestSurface);
}

HRESULT CMemReplayDirect3DDevice9::StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter)
{
  return m_pWrap->StretchRect(pSourceSurface,pSourceRect,pDestSurface,pDestRect,Filter);
}

HRESULT CMemReplayDirect3DDevice9::ColorFill(IDirect3DSurface9* pSurface,CONST RECT* pRect,D3DCOLOR color)
{
  return m_pWrap->ColorFill(pSurface,pRect,color);
}

HRESULT CMemReplayDirect3DDevice9::CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle)
{
  HRESULT hr = m_pWrap->CreateOffscreenPlainSurface(Width,Height,Format,Pool, ppSurface, pSharedHandle);
	if (!FAILED(hr))
		MemReplayAnnotateD3DResource(*ppSurface, Pool, Width * Height);
	return hr;
}

HRESULT CMemReplayDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget)
{
  return m_pWrap->SetRenderTarget(RenderTargetIndex,pRenderTarget);
}

HRESULT CMemReplayDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget)
{
  return m_pWrap->GetRenderTarget(RenderTargetIndex, ppRenderTarget);
}

HRESULT CMemReplayDirect3DDevice9::SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil)
{
  return m_pWrap->SetDepthStencilSurface(pNewZStencil);
}

HRESULT CMemReplayDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface)
{
  return m_pWrap->GetDepthStencilSurface(ppZStencilSurface);
}

HRESULT CMemReplayDirect3DDevice9::BeginScene()
{
  return m_pWrap->BeginScene();
}

HRESULT CMemReplayDirect3DDevice9::EndScene()
{
  return m_pWrap->EndScene();
}

HRESULT CMemReplayDirect3DDevice9::Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil)
{
  return m_pWrap->Clear(Count,pRects,Flags,Color,Z,Stencil);
}

HRESULT CMemReplayDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix)
{
  return m_pWrap->SetTransform(State,pMatrix);
}

HRESULT CMemReplayDirect3DDevice9::GetTransform(D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix)
{
  return m_pWrap->GetTransform(State,pMatrix);
}

HRESULT CMemReplayDirect3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix)
{
  return m_pWrap->MultiplyTransform(State,pMatrix);
}

HRESULT CMemReplayDirect3DDevice9::SetViewport(CONST D3DVIEWPORT9* pViewport)
{
  return m_pWrap->SetViewport(pViewport);
}

HRESULT CMemReplayDirect3DDevice9::GetViewport(D3DVIEWPORT9* pViewport)
{
  return m_pWrap->GetViewport(pViewport);
}

HRESULT CMemReplayDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial)
{
  return m_pWrap->SetMaterial(pMaterial);
}

HRESULT CMemReplayDirect3DDevice9::GetMaterial(D3DMATERIAL9* pMaterial)
{
  return m_pWrap->GetMaterial(pMaterial);
}

HRESULT CMemReplayDirect3DDevice9::SetLight(DWORD Index,CONST D3DLIGHT9* pLight)
{
  return m_pWrap->SetLight(Index,pLight);
}

HRESULT CMemReplayDirect3DDevice9::GetLight(DWORD Index,D3DLIGHT9* pLight)
{
  return m_pWrap->GetLight(Index,pLight);
}

HRESULT CMemReplayDirect3DDevice9::LightEnable(DWORD Index,BOOL Enable)
{
  return m_pWrap->LightEnable(Index,Enable);
}

HRESULT CMemReplayDirect3DDevice9::GetLightEnable(DWORD Index,BOOL* pEnable)
{
  return m_pWrap->GetLightEnable(Index,pEnable);
}

HRESULT CMemReplayDirect3DDevice9::SetClipPlane(DWORD Index,CONST float* pPlane)
{
  return m_pWrap->SetClipPlane(Index,pPlane);
}

HRESULT CMemReplayDirect3DDevice9::GetClipPlane(DWORD Index,float* pPlane)
{
  return m_pWrap->GetClipPlane(Index,pPlane);
}

HRESULT CMemReplayDirect3DDevice9::SetRenderState(D3DRENDERSTATETYPE State,DWORD Value)
{
  return m_pWrap->SetRenderState(State,Value);
}

HRESULT CMemReplayDirect3DDevice9::GetRenderState(D3DRENDERSTATETYPE State,DWORD* pValue)
{
  return m_pWrap->GetRenderState(State,pValue);
}

HRESULT CMemReplayDirect3DDevice9::CreateStateBlock(D3DSTATEBLOCKTYPE Type,IDirect3DStateBlock9** ppSB)
{
  return m_pWrap->CreateStateBlock(Type,ppSB);
}

HRESULT CMemReplayDirect3DDevice9::BeginStateBlock()
{
  return m_pWrap->BeginStateBlock();
}

HRESULT CMemReplayDirect3DDevice9::EndStateBlock(IDirect3DStateBlock9** ppSB)
{
  return m_pWrap->EndStateBlock(ppSB);
}

HRESULT CMemReplayDirect3DDevice9::SetClipStatus(CONST D3DCLIPSTATUS9* pClipStatus)
{
  return m_pWrap->SetClipStatus(pClipStatus);
}

HRESULT CMemReplayDirect3DDevice9::GetClipStatus(D3DCLIPSTATUS9* pClipStatus)
{
  return m_pWrap->GetClipStatus(pClipStatus);
}

HRESULT CMemReplayDirect3DDevice9::GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture)
{
  return m_pWrap->GetTexture(Stage, ppTexture);
}

HRESULT CMemReplayDirect3DDevice9::SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture)
{
  return m_pWrap->SetTexture(Stage,pTexture);
}

HRESULT CMemReplayDirect3DDevice9::GetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue)
{
  return m_pWrap->GetTextureStageState(Stage,Type,pValue);
}

HRESULT CMemReplayDirect3DDevice9::SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value)
{
  return m_pWrap->SetTextureStageState(Stage,Type,Value);
}

HRESULT CMemReplayDirect3DDevice9::GetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD* pValue)
{
  return m_pWrap->GetSamplerState(Sampler,Type, pValue);
}

HRESULT CMemReplayDirect3DDevice9::SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value)
{
  return m_pWrap->SetSamplerState(Sampler,Type,Value);
}

HRESULT CMemReplayDirect3DDevice9::ValidateDevice(DWORD* pNumPasses)
{
  return m_pWrap->ValidateDevice(pNumPasses);
}

HRESULT CMemReplayDirect3DDevice9::SetPaletteEntries(UINT PaletteNumber,CONST PALETTEENTRY* pEntries)
{
  return m_pWrap->SetPaletteEntries(PaletteNumber,pEntries);
}

HRESULT CMemReplayDirect3DDevice9::GetPaletteEntries(UINT PaletteNumber,PALETTEENTRY* pEntries)
{
  return m_pWrap->GetPaletteEntries(PaletteNumber,pEntries);
}

HRESULT CMemReplayDirect3DDevice9::SetCurrentTexturePalette(UINT PaletteNumber)
{
  return m_pWrap->SetCurrentTexturePalette(PaletteNumber);
}

HRESULT CMemReplayDirect3DDevice9::GetCurrentTexturePalette(UINT *PaletteNumber)
{
  return m_pWrap->GetCurrentTexturePalette(PaletteNumber);
}

HRESULT CMemReplayDirect3DDevice9::SetScissorRect(CONST RECT* pRect)
{
  return m_pWrap->SetScissorRect(pRect);
}

HRESULT CMemReplayDirect3DDevice9::GetScissorRect(RECT* pRect)
{
  return m_pWrap->GetScissorRect(pRect);
}

HRESULT CMemReplayDirect3DDevice9::SetSoftwareVertexProcessing(BOOL bSoftware)
{
  return m_pWrap->SetSoftwareVertexProcessing(bSoftware);
}

BOOL CMemReplayDirect3DDevice9::GetSoftwareVertexProcessing()
{
  return m_pWrap->GetSoftwareVertexProcessing();
}

HRESULT CMemReplayDirect3DDevice9::SetNPatchMode(float nSegments)
{
  return m_pWrap->SetNPatchMode(nSegments);
}

float CMemReplayDirect3DDevice9::GetNPatchMode()
{
  return m_pWrap->GetNPatchMode();
}

HRESULT CMemReplayDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount)
{
  return m_pWrap->DrawPrimitive(PrimitiveType,StartVertex,PrimitiveCount);
}

HRESULT CMemReplayDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount)
{
  return m_pWrap->DrawIndexedPrimitive(PrimitiveType,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
}

HRESULT CMemReplayDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride)
{
  return m_pWrap->DrawPrimitiveUP(PrimitiveType,PrimitiveCount,pVertexStreamZeroData,VertexStreamZeroStride);
}

HRESULT CMemReplayDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride)
{
  return m_pWrap->DrawIndexedPrimitiveUP(PrimitiveType,MinVertexIndex,NumVertices,PrimitiveCount, pIndexData,IndexDataFormat,pVertexStreamZeroData,VertexStreamZeroStride);
}

HRESULT CMemReplayDirect3DDevice9::ProcessVertices(UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer9* pDestBuffer,IDirect3DVertexDeclaration9* pVertexDecl,DWORD Flags)
{
  return m_pWrap->ProcessVertices(SrcStartIndex,DestIndex,VertexCount,pDestBuffer,pVertexDecl,Flags);
}

HRESULT CMemReplayDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl)
{
  return m_pWrap->CreateVertexDeclaration(pVertexElements,ppDecl);
}

HRESULT CMemReplayDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl)
{
  return m_pWrap->SetVertexDeclaration(pDecl);
}

HRESULT CMemReplayDirect3DDevice9::GetVertexDeclaration(IDirect3DVertexDeclaration9** ppDecl)
{
  return m_pWrap->GetVertexDeclaration( ppDecl);
}

HRESULT CMemReplayDirect3DDevice9::SetFVF(DWORD FVF)
{
  return m_pWrap->SetFVF(FVF);
}

HRESULT CMemReplayDirect3DDevice9::GetFVF(DWORD* pFVF)
{
  return m_pWrap->GetFVF( pFVF);
}

HRESULT CMemReplayDirect3DDevice9::CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader)
{
  return m_pWrap->CreateVertexShader(pFunction, ppShader);
}

HRESULT CMemReplayDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader)
{
  return m_pWrap->SetVertexShader( pShader);
}

HRESULT CMemReplayDirect3DDevice9::GetVertexShader(IDirect3DVertexShader9** ppShader)
{
  return m_pWrap->GetVertexShader( ppShader);
}

HRESULT CMemReplayDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount)
{
  return m_pWrap->SetVertexShaderConstantF(StartRegister,pConstantData,Vector4fCount);
}

HRESULT CMemReplayDirect3DDevice9::GetVertexShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount)
{
  return m_pWrap->GetVertexShaderConstantF(StartRegister,pConstantData,Vector4fCount);
}

HRESULT CMemReplayDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount)
{
  return m_pWrap->SetVertexShaderConstantI(StartRegister,pConstantData,Vector4iCount);
}

HRESULT CMemReplayDirect3DDevice9::GetVertexShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount)
{
  return m_pWrap->GetVertexShaderConstantI(StartRegister,pConstantData,Vector4iCount);
}

HRESULT CMemReplayDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount)
{
  return m_pWrap->SetVertexShaderConstantB(StartRegister,pConstantData,BoolCount);
}

HRESULT CMemReplayDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount)
{
  return m_pWrap->GetVertexShaderConstantB(StartRegister,pConstantData,BoolCount);
}

HRESULT CMemReplayDirect3DDevice9::SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
{
  return m_pWrap->SetStreamSource(StreamNumber,pStreamData,OffsetInBytes,Stride);
}

HRESULT CMemReplayDirect3DDevice9::GetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9** ppStreamData,UINT* OffsetInBytes,UINT* pStride)
{
  return m_pWrap->GetStreamSource(StreamNumber, ppStreamData, OffsetInBytes, pStride);
}

HRESULT CMemReplayDirect3DDevice9::SetStreamSourceFreq(UINT StreamNumber,UINT Divider)
{
  return m_pWrap->SetStreamSourceFreq(StreamNumber,Divider);
}

HRESULT CMemReplayDirect3DDevice9::GetStreamSourceFreq(UINT StreamNumber,UINT* Divider)
{
  return m_pWrap->GetStreamSourceFreq(StreamNumber,Divider);
}

HRESULT CMemReplayDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData)
{
  return m_pWrap->SetIndices( pIndexData);
}

HRESULT CMemReplayDirect3DDevice9::GetIndices(IDirect3DIndexBuffer9** ppIndexData)
{
  return m_pWrap->GetIndices( ppIndexData);
}

HRESULT CMemReplayDirect3DDevice9::CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader)
{
  return m_pWrap->CreatePixelShader(pFunction,ppShader);
}

HRESULT CMemReplayDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader)
{
  return m_pWrap->SetPixelShader( pShader);
}

HRESULT CMemReplayDirect3DDevice9::GetPixelShader(IDirect3DPixelShader9** ppShader)
{
  return m_pWrap->GetPixelShader( ppShader);
}

HRESULT CMemReplayDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount)
{
  return m_pWrap->SetPixelShaderConstantF(StartRegister,pConstantData,Vector4fCount);
}

HRESULT CMemReplayDirect3DDevice9::GetPixelShaderConstantF(UINT StartRegister,float* pConstantData,UINT Vector4fCount)
{
  return m_pWrap->GetPixelShaderConstantF(StartRegister,pConstantData,Vector4fCount);
}

HRESULT CMemReplayDirect3DDevice9::SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount)
{
  return m_pWrap->SetPixelShaderConstantI(StartRegister,pConstantData,Vector4iCount);
}

HRESULT CMemReplayDirect3DDevice9::GetPixelShaderConstantI(UINT StartRegister,int* pConstantData,UINT Vector4iCount)
{
  return m_pWrap->GetPixelShaderConstantI(StartRegister,pConstantData,Vector4iCount);
}

HRESULT CMemReplayDirect3DDevice9::SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT  BoolCount)
{
  return m_pWrap->SetPixelShaderConstantB(StartRegister,pConstantData,BoolCount);
}

HRESULT CMemReplayDirect3DDevice9::GetPixelShaderConstantB(UINT StartRegister,BOOL* pConstantData,UINT BoolCount)
{
  return m_pWrap->GetPixelShaderConstantB(StartRegister,pConstantData,BoolCount);
}

HRESULT CMemReplayDirect3DDevice9::DrawRectPatch(UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo)
{
  return m_pWrap->DrawRectPatch(Handle,pNumSegs,pRectPatchInfo);
}

HRESULT CMemReplayDirect3DDevice9::DrawTriPatch(UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo)
{
  return m_pWrap->DrawTriPatch(Handle,pNumSegs,pTriPatchInfo);
}

HRESULT CMemReplayDirect3DDevice9::DeletePatch(UINT Handle)
{
  return m_pWrap->DeletePatch(Handle);
}

HRESULT CMemReplayDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery)
{
  return m_pWrap->CreateQuery(Type, ppQuery);
}

#endif

#ifdef MEMREPLAY_WRAP_D3D11

CMemReplayDirect3DDevice11::CMemReplayDirect3DDevice11(ID3D11Device* pWrap)
	: m_pWrap(pWrap)
{
}

HRESULT CMemReplayDirect3DDevice11::QueryInterface(REFIID riid, void** ppvObj)
{
  return m_pWrap->QueryInterface(riid, ppvObj);
}
ULONG CMemReplayDirect3DDevice11::AddRef()
{
  return m_pWrap->AddRef();
}
ULONG CMemReplayDirect3DDevice11::Release()
{
  return m_pWrap->Release();
}

HRESULT CMemReplayDirect3DDevice11::GetDeviceRemovedReason( void)
{
  return m_pWrap->GetDeviceRemovedReason();
}

HRESULT CMemReplayDirect3DDevice11::SetExceptionMode(UINT RaiseFlags)
{
  return m_pWrap->SetExceptionMode(RaiseFlags);
}

UINT CMemReplayDirect3DDevice11::GetExceptionMode( void)
{
  return m_pWrap->GetExceptionMode();
}

HRESULT CMemReplayDirect3DDevice11::GetPrivateData( 
  /* [in] */ REFGUID guid,
  /* [out][in] */ UINT *pDataSize,
  /* [size_is][out] */ void *pData)
{
  return m_pWrap->GetPrivateData(guid, pDataSize, pData);
}

HRESULT CMemReplayDirect3DDevice11::SetPrivateData( 
  /* [in] */ REFGUID guid,
  /* [in] */ UINT DataSize,
  /* [size_is][in] */ const void *pData)
{
  return m_pWrap->SetPrivateData(guid, DataSize, pData);
}

HRESULT CMemReplayDirect3DDevice11::SetPrivateDataInterface( 
  /* [in] */ REFGUID guid,
  /* [in] */ const IUnknown *pData)
{
  return m_pWrap->SetPrivateDataInterface(guid, pData);
}

HRESULT CMemReplayDirect3DDevice11::CreateBuffer( 
  /* [in] */ const D3D11_BUFFER_DESC *pDesc,
  /* [in] */ const D3D11_SUBRESOURCE_DATA *pInitialData,
  /* [out] */ ID3D11Buffer **ppBuffer)
{
	HRESULT hr = m_pWrap->CreateBuffer(pDesc, pInitialData, ppBuffer);
	if (!FAILED(hr))
	{
		ID3D11Buffer* pBuffer = *ppBuffer;

		D3D11_BUFFER_DESC desc;
		pBuffer->GetDesc(&desc);

		MemReplayAnnotateD3DResource(pBuffer, desc.ByteWidth);
	}

	return hr;
}

static size_t ComputeSurfaceSize(DWORD width, DWORD height, DWORD depth, DXGI_FORMAT fmt)
{
	switch (fmt)
	{
	default:
	case DXGI_FORMAT_UNKNOWN:
		return width * height * depth;

		case DXGI_FORMAT_R32G32B32A32_TYPELESS:
		case DXGI_FORMAT_R32G32B32A32_FLOAT:
		case DXGI_FORMAT_R32G32B32A32_UINT:
		case DXGI_FORMAT_R32G32B32A32_SINT:
			return width * height * depth * 16;

		case DXGI_FORMAT_R32G32B32_TYPELESS:
		case DXGI_FORMAT_R32G32B32_FLOAT:
		case DXGI_FORMAT_R32G32B32_UINT:
		case DXGI_FORMAT_R32G32B32_SINT:
		case DXGI_FORMAT_R16G16B16A16_TYPELESS:
		case DXGI_FORMAT_R16G16B16A16_FLOAT:
		case DXGI_FORMAT_R16G16B16A16_UNORM:
		case DXGI_FORMAT_R16G16B16A16_UINT:
		case DXGI_FORMAT_R16G16B16A16_SNORM:
		case DXGI_FORMAT_R16G16B16A16_SINT:
		case DXGI_FORMAT_R32G32_TYPELESS:
		case DXGI_FORMAT_R32G32_FLOAT:
		case DXGI_FORMAT_R32G32_UINT:
		case DXGI_FORMAT_R32G32_SINT:
		case DXGI_FORMAT_R32G8X24_TYPELESS:
		case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
		case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
		case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
			return width * height * depth * 8;

		case DXGI_FORMAT_R10G10B10A2_TYPELESS:
		case DXGI_FORMAT_R10G10B10A2_UNORM:
		case DXGI_FORMAT_R10G10B10A2_UINT:
		case DXGI_FORMAT_R11G11B10_FLOAT:
		case DXGI_FORMAT_R8G8B8A8_TYPELESS:
		case DXGI_FORMAT_R8G8B8A8_UNORM:
		case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
		case DXGI_FORMAT_R8G8B8A8_UINT:
		case DXGI_FORMAT_R8G8B8A8_SNORM:
		case DXGI_FORMAT_R8G8B8A8_SINT:
		case DXGI_FORMAT_R16G16_TYPELESS:
		case DXGI_FORMAT_R16G16_FLOAT:
		case DXGI_FORMAT_R16G16_UNORM:
		case DXGI_FORMAT_R16G16_UINT:
		case DXGI_FORMAT_R16G16_SNORM:
		case DXGI_FORMAT_R16G16_SINT:
		case DXGI_FORMAT_R32_TYPELESS:
		case DXGI_FORMAT_D32_FLOAT:
		case DXGI_FORMAT_R32_FLOAT:
		case DXGI_FORMAT_R32_UINT:
		case DXGI_FORMAT_R32_SINT:
		case DXGI_FORMAT_R24G8_TYPELESS:
		case DXGI_FORMAT_D24_UNORM_S8_UINT:
		case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
		case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
		case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
		case DXGI_FORMAT_R8G8_B8G8_UNORM:
		case DXGI_FORMAT_G8R8_G8B8_UNORM:
		case DXGI_FORMAT_B8G8R8A8_UNORM:
		case DXGI_FORMAT_B8G8R8X8_UNORM:
			return width * height * depth * 4;

		case DXGI_FORMAT_R8G8_TYPELESS:
		case DXGI_FORMAT_R8G8_UNORM:
		case DXGI_FORMAT_R8G8_UINT:
		case DXGI_FORMAT_R8G8_SNORM:
		case DXGI_FORMAT_R8G8_SINT:
		case DXGI_FORMAT_R16_TYPELESS:
		case DXGI_FORMAT_R16_FLOAT:
		case DXGI_FORMAT_D16_UNORM:
		case DXGI_FORMAT_R16_UNORM:
		case DXGI_FORMAT_R16_UINT:
		case DXGI_FORMAT_R16_SNORM:
		case DXGI_FORMAT_R16_SINT:
		case DXGI_FORMAT_B5G6R5_UNORM:
		case DXGI_FORMAT_B5G5R5A1_UNORM:
			return width * height * depth * 2;

		case DXGI_FORMAT_R8_TYPELESS:
		case DXGI_FORMAT_R8_UNORM:
		case DXGI_FORMAT_R8_UINT:
		case DXGI_FORMAT_R8_SNORM:
		case DXGI_FORMAT_R8_SINT:
		case DXGI_FORMAT_A8_UNORM:
			return width * height * depth;

		case DXGI_FORMAT_R1_UNORM:
			return width * height * depth / 8;

		case DXGI_FORMAT_BC1_TYPELESS:
		case DXGI_FORMAT_BC1_UNORM:
		case DXGI_FORMAT_BC1_UNORM_SRGB:
			return width * height * depth / 2;

		case DXGI_FORMAT_BC2_TYPELESS:
		case DXGI_FORMAT_BC2_UNORM:
		case DXGI_FORMAT_BC2_UNORM_SRGB:
		case DXGI_FORMAT_BC3_TYPELESS:
		case DXGI_FORMAT_BC3_UNORM:
		case DXGI_FORMAT_BC3_UNORM_SRGB:
		case DXGI_FORMAT_BC4_TYPELESS:
		case DXGI_FORMAT_BC4_UNORM:
		case DXGI_FORMAT_BC4_SNORM:
		case DXGI_FORMAT_BC5_TYPELESS:
		case DXGI_FORMAT_BC5_UNORM:
		case DXGI_FORMAT_BC5_SNORM:
			return width * height * depth;
	}
}

static size_t ComputeSurfaceSize(DWORD width, DWORD height, DWORD depth, DWORD mipLevels, DXGI_FORMAT fmt)
{
	size_t sz = 0;

	for (DWORD i = 0; i < mipLevels; ++ i, width = std::max<DWORD>(width >> 1, 1), height = std::max<DWORD>(height >> 1, 1), depth = std::max<DWORD>(depth >> 1, 1))
		sz += ComputeSurfaceSize(width, height, depth, fmt);

	return sz;
}

HRESULT CMemReplayDirect3DDevice11::CreateTexture1D( 
  /* [in] */ const D3D11_TEXTURE1D_DESC *pDesc,
  /* [in] */ const D3D11_SUBRESOURCE_DATA *pInitialData,
  /* [out] */ ID3D11Texture1D **ppTexture1D)
{
  HRESULT hr = m_pWrap->CreateTexture1D(pDesc, pInitialData, ppTexture1D);

	if (!FAILED(hr))
	{
		ID3D11Texture1D* pTexture = *ppTexture1D;

		D3D11_TEXTURE1D_DESC desc;
		pTexture->GetDesc(&desc);

		MemReplayAnnotateD3DResource(pTexture, desc.ArraySize * ComputeSurfaceSize(desc.Width, 1, 1, desc.MipLevels, desc.Format));
	}

	return hr;
}

HRESULT CMemReplayDirect3DDevice11::CreateTexture2D( 
  /* [in] */ const D3D11_TEXTURE2D_DESC *pDesc,
  /* [in] */ const D3D11_SUBRESOURCE_DATA *pInitialData,
  /* [out] */ ID3D11Texture2D **ppTexture2D)
{
  HRESULT hr = m_pWrap->CreateTexture2D(pDesc, pInitialData, ppTexture2D);

	if (!FAILED(hr))
	{
		ID3D11Texture2D* pTexture = *ppTexture2D;

		D3D11_TEXTURE2D_DESC desc;
		pTexture->GetDesc(&desc);

		MemReplayAnnotateD3DResource(pTexture, desc.ArraySize * ComputeSurfaceSize(desc.Width, desc.Height, 1, desc.MipLevels, desc.Format));
	}

	return hr;
}

HRESULT CMemReplayDirect3DDevice11::CreateTexture3D( 
  /* [in] */ const D3D11_TEXTURE3D_DESC *pDesc,
  /* [in] */ const D3D11_SUBRESOURCE_DATA *pInitialData,
  /* [out] */ ID3D11Texture3D **ppTexture3D)
{
  HRESULT hr = m_pWrap->CreateTexture3D(pDesc, pInitialData, ppTexture3D);

	if (!FAILED(hr))
	{
		ID3D11Texture3D* pTexture = *ppTexture3D;

		D3D11_TEXTURE3D_DESC desc;
		pTexture->GetDesc(&desc);

		MemReplayAnnotateD3DResource(pTexture, ComputeSurfaceSize(desc.Width, desc.Height, desc.Depth, desc.MipLevels, desc.Format));
	}

	return hr;
}

HRESULT CMemReplayDirect3DDevice11::CreateShaderResourceView( 
  /* [in] */ ID3D11Resource *pResource,
  /* [in] */ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc,
  /* [out] */ ID3D11ShaderResourceView **ppSRView)
{
  return m_pWrap->CreateShaderResourceView(pResource, pDesc, ppSRView);
}

HRESULT CMemReplayDirect3DDevice11::CreateRenderTargetView( 
  /* [in] */ ID3D11Resource *pResource,
  /* [in] */ const D3D11_RENDER_TARGET_VIEW_DESC *pDesc,
  /* [out] */ ID3D11RenderTargetView **ppRTView)
{
  return m_pWrap->CreateRenderTargetView(pResource, pDesc, ppRTView);
}

HRESULT CMemReplayDirect3DDevice11::CreateDepthStencilView( 
  /* [in] */ ID3D11Resource *pResource,
  /* [in] */ const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc,
  /* [out] */ ID3D11DepthStencilView **ppDepthStencilView)
{
  return m_pWrap->CreateDepthStencilView(pResource, pDesc, ppDepthStencilView);
}

HRESULT CMemReplayDirect3DDevice11::CreateInputLayout( 
  /* [size_is][in] */ const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
  /* [in] */ UINT NumElements,
  /* [in] */ const void *pShaderBytecodeWithInputSignature,
	/* [in] */ SIZE_T BytecodeLength,
  /* [out] */ ID3D11InputLayout **ppInputLayout)
{
  return m_pWrap->CreateInputLayout(pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength, ppInputLayout);
}

HRESULT CMemReplayDirect3DDevice11::CreateVertexShader( 
  /* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11VertexShader **ppVertexShader)
{
  return m_pWrap->CreateVertexShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppVertexShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateGeometryShader( 
  /* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11GeometryShader **ppGeometryShader)
{
  return m_pWrap->CreateGeometryShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppGeometryShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateGeometryShaderWithStreamOutput( 
	/* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [size_is][in] */ const D3D11_SO_DECLARATION_ENTRY *pSODeclaration,
	/* [in] */ UINT NumEntries,
	/* [in] */ const UINT *pBufferStrides,
	/* [in] */ UINT NumStrides,
	/* [in] */ UINT RasterizedStream,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11GeometryShader **ppGeometryShader)
{
  return m_pWrap->CreateGeometryShaderWithStreamOutput(pShaderBytecode, BytecodeLength, pSODeclaration, NumEntries, pBufferStrides, NumStrides, RasterizedStream, pClassLinkage, ppGeometryShader);
}

HRESULT CMemReplayDirect3DDevice11::CreatePixelShader( 
  /* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11PixelShader **ppPixelShader)
{
  return m_pWrap->CreatePixelShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppPixelShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateBlendState( 
  /* [in] */ const D3D11_BLEND_DESC *pBlendStateDesc,
  /* [out] */ ID3D11BlendState **ppBlendState)
{
  return m_pWrap->CreateBlendState(pBlendStateDesc, ppBlendState);
}

HRESULT CMemReplayDirect3DDevice11::CreateDepthStencilState( 
  /* [in] */ const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc,
  /* [out] */ ID3D11DepthStencilState **ppDepthStencilState)
{
  return m_pWrap->CreateDepthStencilState(pDepthStencilDesc, ppDepthStencilState);
}

HRESULT CMemReplayDirect3DDevice11::CreateRasterizerState( 
  /* [in] */ const D3D11_RASTERIZER_DESC *pRasterizerDesc,
  /* [out] */ ID3D11RasterizerState **ppRasterizerState)
{
  return m_pWrap->CreateRasterizerState(pRasterizerDesc, ppRasterizerState);
}

HRESULT CMemReplayDirect3DDevice11::CreateSamplerState( 
  /* [in] */ const D3D11_SAMPLER_DESC *pSamplerDesc,
  /* [out] */ ID3D11SamplerState **ppSamplerState)
{
  return m_pWrap->CreateSamplerState(pSamplerDesc, ppSamplerState);
}

HRESULT CMemReplayDirect3DDevice11::CreateQuery( 
  /* [in] */ const D3D11_QUERY_DESC *pQueryDesc,
  /* [out] */ ID3D11Query **ppQuery)
{
  return m_pWrap->CreateQuery(pQueryDesc, ppQuery);
}

HRESULT CMemReplayDirect3DDevice11::CreatePredicate( 
  /* [in] */ const D3D11_QUERY_DESC *pPredicateDesc,
  /* [out] */ ID3D11Predicate **ppPredicate)
{
  return m_pWrap->CreatePredicate(pPredicateDesc, ppPredicate);
}

HRESULT CMemReplayDirect3DDevice11::CreateUnorderedAccessView( 
														/* [in] */ ID3D11Resource *pResource, 
														/* [in] */ const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, 
														/* [out] */ ID3D11UnorderedAccessView **ppUAView )
{
	return m_pWrap->CreateUnorderedAccessView(pResource, pDesc, ppUAView);
}

HRESULT CMemReplayDirect3DDevice11::CreateHullShader(
	/* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11HullShader **ppHullShader
	)
{
	return m_pWrap->CreateHullShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppHullShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateDomainShader(
	/* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11DomainShader **ppDomainShader
	)
{
	return m_pWrap->CreateDomainShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppDomainShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateComputeShader(
	/* [in] */ const void *pShaderBytecode,
	/* [in] */ SIZE_T BytecodeLength,
	/* [in] */ ID3D11ClassLinkage *pClassLinkage,
	/* [out] */ ID3D11ComputeShader **ppComputeShader
	)
{
	return m_pWrap->CreateComputeShader(pShaderBytecode, BytecodeLength, pClassLinkage, ppComputeShader);
}

HRESULT CMemReplayDirect3DDevice11::CreateClassLinkage(
	/* [out] */ ID3D11ClassLinkage **ppLinkage
	)
{
	return m_pWrap->CreateClassLinkage(ppLinkage);
}

HRESULT CMemReplayDirect3DDevice11::CreateDeferredContext(
	/* [in] */ UINT ContextFlags,
	/* [out] */ ID3D11DeviceContext **ppDeferredContext
	)
{
	return m_pWrap->CreateDeferredContext(ContextFlags, ppDeferredContext);
}

HRESULT CMemReplayDirect3DDevice11::CheckFeatureSupport(
	/* [in] */ D3D11_FEATURE Feature,
	/* [in] */ void *pFeatureSupportData,
	/* [in] */ UINT FeatureSupportDataSize
	)
{
	return m_pWrap->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize);
}

D3D_FEATURE_LEVEL CMemReplayDirect3DDevice11::GetFeatureLevel()
{
	return m_pWrap->GetFeatureLevel();
}

void CMemReplayDirect3DDevice11::GetImmediateContext(
	/* [out] */ ID3D11DeviceContext **ppImmediateContext
	)
{
	return m_pWrap->GetImmediateContext(ppImmediateContext);
}

HRESULT CMemReplayDirect3DDevice11::CreateCounter( 
  /* [in] */ const D3D11_COUNTER_DESC *pCounterDesc,
  /* [out] */ ID3D11Counter **ppCounter)
{
  return m_pWrap->CreateCounter(pCounterDesc, ppCounter);
}

HRESULT CMemReplayDirect3DDevice11::CheckFormatSupport( 
  /* [in] */ DXGI_FORMAT Format,
  /* [retval][out] */ UINT *pFormatSupport)
{
  return m_pWrap->CheckFormatSupport(Format, pFormatSupport);
}

HRESULT CMemReplayDirect3DDevice11::CheckMultisampleQualityLevels( 
  DXGI_FORMAT Format,
  /* [in] */ UINT SampleCount,
  /* [retval][out] */ UINT *pNumQualityLevels)
{
  return m_pWrap->CheckMultisampleQualityLevels(Format, SampleCount, pNumQualityLevels);
}

void CMemReplayDirect3DDevice11::CheckCounterInfo( 
  /* [retval][out] */ D3D11_COUNTER_INFO *pCounterInfo)
{
  m_pWrap->CheckCounterInfo(pCounterInfo);
}

HRESULT CMemReplayDirect3DDevice11::CheckCounter( 
  /*  */ 
  __in  const D3D11_COUNTER_DESC *pDesc,
  /*  */ 
  __out  D3D11_COUNTER_TYPE *pType,
  /*  */ 
  __out  UINT *pActiveCounters,
  /*  */ 
  __out_ecount_opt(*pNameLength)  LPSTR wszName,
  /*  */ 
  __inout_opt  UINT *pNameLength,
  /*  */ 
  __out_ecount_opt(*pUnitsLength)  LPSTR wszUnits,
  /*  */ 
  __inout_opt  UINT *pUnitsLength,
  /*  */ 
  __out_ecount_opt(*pDescriptionLength)  LPSTR wszDescription,
  /*  */ 
  __inout_opt  UINT *pDescriptionLength)
{
  return m_pWrap->CheckCounter(pDesc, pType, pActiveCounters, wszName, pNameLength, wszUnits, pUnitsLength, wszDescription, pDescriptionLength);
}

HRESULT CMemReplayDirect3DDevice11::OpenSharedResource(
  HANDLE hResource,
  REFIID ReturnedInterface,
  void ** ppResource
  )
{
  return m_pWrap->OpenSharedResource(hResource, ReturnedInterface, ppResource);
}

UINT CMemReplayDirect3DDevice11::GetCreationFlags()
{
  return m_pWrap->GetCreationFlags();
}

#endif

void CD3D9Renderer::MemReplayWrapD3DDevice()
{
#if CAPTURE_REPLAY_LOG
	CryReplayInfo replayInfo;
	CryGetIMemReplay()->GetInfo(replayInfo);

	if (replayInfo.filename)
	{
#ifdef MEMREPLAY_WRAP_D3D9
		m_pd3dDevice = new CMemReplayDirect3DDevice9(m_pd3dDevice);
#endif
#ifdef MEMREPLAY_WRAP_D3D11
		m_pd3dDevice = new CMemReplayDirect3DDevice11(m_pd3dDevice);
#endif
	}
#endif
}
